//
// Created by MoonlightSW on 2017/7/11.
//

#include <jni.h>
#include <sys/time.h>
#include <android/log.h>
#include <TempAlg.h>

#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,"JNIHelper",__VA_ARGS__)

extern "C" {

long getCurrentTime() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}

JNIEXPORT jobject JNICALL
Java_com_proton_carepatchtemp_utils_JNIUtils_getTemp(JNIEnv *env, jclass type, jfloatArray temps,
                                                     jobject lastTempImg) {

    jclass lastTempImgClass = env->GetObjectClass(lastTempImg);
    jfieldID handleField = env->GetFieldID(lastTempImgClass, "handle", "Z");
    jfieldID startInd = env->GetFieldID(lastTempImgClass, "startInd", "I");
    jfieldID stickNField = env->GetFieldID(lastTempImgClass, "stickN", "I");
    jfieldID declineField = env->GetFieldID(lastTempImgClass, "decline", "I");
    jfieldID predIndField = env->GetFieldID(lastTempImgClass, "predInd", "I");
    jfieldID stabTField = env->GetFieldID(lastTempImgClass, "stabT", "F");
    jfieldID predTempField = env->GetFieldID(lastTempImgClass, "predTemp", "F");

    jboolean handleValue = env->GetBooleanField(lastTempImg, handleField);
    jint startIndValue = env->GetIntField(lastTempImg, startInd);
    jint stickNValue = env->GetIntField(lastTempImg, stickNField);
    jint declineValue = env->GetIntField(lastTempImg, declineField);
    jint predIndValue = env->GetIntField(lastTempImg, predIndField);
    jfloat stabTValue = env->GetFloatField(lastTempImg, stabTField);
    jfloat predTempValue = env->GetFloatField(lastTempImg, predTempField);

    TempImg tempImg = TempImg();
    tempImg.decline = declineValue;
    tempImg.handle = handleValue;
    tempImg.startInd = startIndValue;
    tempImg.predInd = predIndValue;
    tempImg.predTemp = predTempValue;
    tempImg.stabT = stabTValue;
    tempImg.stickN = stickNValue;

    jint size = env->GetArrayLength(temps);
    LOGE("算法开始,size = %d,decline = %d,startInd = %d,preInd = %d,stabT = %f,predTempValue = %f,stickN = %d",
         size, declineValue, startIndValue, predIndValue, stabTValue, predTempValue, stickNValue);
    vector<float> tempsDoubles(size);
    env->GetFloatArrayRegion(temps, 0, size, &tempsDoubles[0]);
    TempImg resultTemp = getTemp(tempsDoubles, tempImg.stabT, tempImg.predTemp, tempImg.startInd,
                                 tempImg.predInd, tempImg.stickN, tempImg.decline, tempImg.handle);

    LOGE("算法结束,size = %lf,decline = %d,startInd = %d,preInd = %d,stabT = %f,predTempValue = %f,stickN = %d",
         resultTemp.stabT, resultTemp.decline, resultTemp.startInd, resultTemp.predInd,
         resultTemp.stabT, resultTemp.predTemp, resultTemp.stickN);
    jclass tempImgClass = env->FindClass("com/proton/carepatchtemp/database/TempImg");
    jmethodID tempImgClint = env->GetMethodID(tempImgClass, "<init>", "()V");
    jobject tempImgObj = env->NewObject(tempImgClass, tempImgClint);

    env->SetFloatField(tempImgObj, env->GetFieldID(tempImgClass, "stabT", "F"), resultTemp.stabT);
    env->SetFloatField(tempImgObj, env->GetFieldID(tempImgClass, "predTemp", "F"),
                       resultTemp.predTemp);
    env->SetIntField(tempImgObj, env->GetFieldID(tempImgClass, "startInd", "I"),
                     resultTemp.startInd);
    env->SetIntField(tempImgObj, env->GetFieldID(tempImgClass, "stickN", "I"), resultTemp.stickN);
    env->SetIntField(tempImgObj, env->GetFieldID(tempImgClass, "decline", "I"), resultTemp.decline);
    env->SetIntField(tempImgObj, env->GetFieldID(tempImgClass, "predInd", "I"), resultTemp.predInd);
    env->SetBooleanField(tempImgObj, env->GetFieldID(tempImgClass, "handle", "Z"),
                         (jboolean) resultTemp.handle);
    return tempImgObj;
}
}